package org.codefilarete.stalactite.engine.configurer.builder.embeddable;

import javax.annotation.Nullable;

import org.codefilarete.reflection.ReadWritePropertyAccessPoint;
import org.codefilarete.stalactite.sql.ddl.Size;
import org.codefilarete.stalactite.sql.ddl.structure.Table;
import org.codefilarete.stalactite.sql.statement.binder.ParameterBinder;
import org.codefilarete.stalactite.sql.statement.binder.ParameterBinderRegistry.EnumBindType;
import org.codefilarete.tool.function.Converter;

/**
 * Small contract for defining property configuration storage
 *
 * @param <C> property owner type
 * @param <O> property type
 */
public interface EmbeddableLinkage<C, O> {
	
	ReadWritePropertyAccessPoint<C, O> getAccessor();
	
	@Nullable
	String getFieldName();
	
	@Nullable
	String getColumnName();
	
	@Nullable
	Size getColumnSize();
	
	Class<O> getColumnType();
	
	@Nullable
	Table getExtraTable();
	
	@Nullable
	ParameterBinder<Object> getParameterBinder();
	
	/**
	 * Gives the choice made by the user to define how to bind enum values: by name or ordinal.
	 *
	 * @return null if no info was given
	 */
	@Nullable
	EnumBindType getEnumBindType();
	
	/**
	 *
	 * @return null if the user didn't mention nullability, then we'll make a choice for him according to property type
	 */
	@Nullable
	Boolean isNullable();
	
	boolean isReadonly();
	
	boolean isUnique();
	
	boolean isSetByConstructor();
	
	@Nullable
	Converter<?, O> getReadConverter();
	
	@Nullable
	Converter<O, ?> getWriteConverter();
}
